package logic

import (
	"context"
	"fmt"
	"strconv"
	"time"

	"mall/common/enumx"
	"mall/common/moneyx"
	"mall/service/user/model"
	"mall/service/user/rpc/internal/svc"
	"mall/service/user/rpc/types/user"

	"github.com/sirupsen/logrus"
	"github.com/zeromicro/go-zero/core/logx"
)

type BackendSetMemberMetaLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendSetMemberMetaLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendSetMemberMetaLogic {
	return &BackendSetMemberMetaLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BackendSetMemberMetaLogic) BackendSetMemberMeta(in *user.BackendSetMemberMetaReq) (*user.BackendSetMemberMetaResp, error) {
	if len(in.TaskMeta) == 0 {
		return &user.BackendSetMemberMetaResp{}, nil
	}

	var uids []any
	pointUidTimesMap := make(map[int64]int)
	var gemUids []uint64
	for _, metum := range in.TaskMeta {
		uids = append(uids, metum.Id)
	}

	if in.TaskName != "" {
		logMap := make(map[uint64]uint64)
		filterMap := make(map[string]map[string][]any)
		filterMap[model.UserTaskLogColumns.UserID] = map[string][]any{
			"in": uids,
		}
		filterMap[model.UserTaskLogColumns.TaskSlug] = map[string][]any{
			"equalTo": []any{in.TaskName},
		}
		logList, _, listErr := l.svcCtx.User.GetTaskLogList(l.ctx, model.M{
			"latest": "1",
		}, -1, filterMap)
		if listErr != nil {
			logrus.Info(fmt.Sprintf("BackendSetMemberMeta GetTaskLogList err: %+v", listErr))
			return nil, listErr
		}

		if len(logList) > 0 {
			for _, log := range logList {
				if log.UserID > 0 && log.ID > 0 {
					logMap[log.UserID] = log.ID
				}
			}
		}

		now := time.Now()
		for _, metum := range in.TaskMeta {
			if metum.Uid > 0 {
				uid := metum.Id
				log := &model.UserTaskLog{
					UserID:    uint64(uid),
					TaskSlug:  in.TaskName,
					Status:    uint8(enumx.ObjectStatusAproved),
					CreatedAt: now,
					UpdatedAt: now,
				}
				err := l.svcCtx.User.InsertTaskLog(l.ctx, log)
				if err != nil {
					logrus.Info(fmt.Sprintf("BackendSetMemberMeta InsertTaskLog err: %+v", err))
				}

				if in.TaskPoint > 0 {
					transLog := &model.UserTransactionLog{
						UserID:       uint64(uid),
						AssetType:    3,
						ChangeType:   0,
						ChangeAmount: strconv.FormatInt(int64(in.TaskPoint), 10),
						SourceType:   6,
						SourceID:     uint64(metum.Uid),
						Desc:         metum.Key + " " + metum.Value,
						Status:       uint8(enumx.ObjectStatusAproved),
						CreatedAt:    now,
						UpdatedAt:    now,
					}
					err := l.svcCtx.User.InsertTransactionLog(l.ctx, transLog)
					if err != nil {
						logrus.Info(fmt.Sprintf("BackendSetMemberMeta InsertTransactionLog err: %+v", err))
					} else {
						if _, exist := pointUidTimesMap[uid]; !exist {
							pointUidTimesMap[uid] = 1
						} else {
							pointUidTimesMap[uid] = pointUidTimesMap[uid] + 1
						}
					}
				}
				if in.TaskGem > 0 {
					if _, ok := logMap[uint64(uid)]; ok { // 非首次完成此类任务，不再奖励宝石
						continue
					}

					transLog := &model.UserTransactionLog{
						UserID:       uint64(uid),
						AssetType:    2,
						ChangeType:   0,
						ChangeAmount: moneyx.FormatGem(int64(in.TaskGem)),
						SourceType:   6,
						SourceID:     uint64(metum.Uid),
						Desc:         metum.Key + " " + metum.Value,
						Status:       uint8(enumx.ObjectStatusAproved),
						CreatedAt:    now,
						UpdatedAt:    now,
					}
					err := l.svcCtx.User.InsertTransactionLog(l.ctx, transLog)
					if err != nil {
						logrus.Info(fmt.Sprintf("BackendSetMemberMeta InsertTransactionLog err: %+v", err))
					} else {
						logMap[uint64(uid)] = uint64(uid)
						gemUids = append(gemUids, uint64(uid))
					}
				}
			}
		}

		for uid, times := range pointUidTimesMap {
			err := l.svcCtx.CurrentUser.IncreaseIntegralBatch(l.ctx, nil, []uint64{uint64(uid)}, int(in.TaskPoint) * times)
			if err != nil {
				logrus.Info(fmt.Sprintf("BackendSetMemberMeta IncreaseIntegralBatch err: %+v", err))
			}
		}
		if len(gemUids) > 0 {
			err := l.svcCtx.CurrentUser.IncreaseBalanceBatch(l.ctx, nil, gemUids, int(in.TaskGem))
			if err != nil {
				logrus.Info(fmt.Sprintf("BackendSetMemberMeta IncreaseBalanceBatch err: %+v", err))
			}
		}
	}

	return &user.BackendSetMemberMetaResp{}, nil
}
